import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
import store from '../../redux/index'
import { setToken, setUserInfo } from '../../redux/actions/basic'
import { history } from '../../router/index'
import { message } from 'antd'

export interface UploadRes {
  filename: string
  id: string
  url: string
}

export const instance: AxiosInstance = axios.create({
  headers: {
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache'
  },
  timeout: 1000 * 120
})

instance.interceptors.request.use(function (config) {
  // config.url = `/api${config.url}`;
  return config
})

type instanceType = 'get' | 'delete' | 'post' | 'put'

interface Response {
  message: string
  data: any
  status: number
}

type RequestFn = (url: string, data?: any, config?: AxiosRequestConfig) => Promise<Response>

/**
 * 请求方法
 * @param {*} type 请求类型
 */
function request (type: instanceType, isAuth: boolean): RequestFn {
  return async function (url: string, data: any = {}, config: AxiosRequestConfig = {}): Promise<Response> {
    const { basic } = store.getState()
    const { token, userInfo } = basic
    const option = {
      url,
      method: type,
      ...config
    }
    if (isAuth) {
      option.headers = {
        Authorization: `Bearer ${token}`
      }
      if (data instanceof FormData) {
        data.append('uid', userInfo.id)
      } else {
        data.uid = userInfo.id
      }
    }
    if (type === 'get' || type === 'delete') {
      option.params = data
    } else {
      option.data = data
    }
    return await new Promise((resolve, reject) => {
      instance(option).then((res) => {
        const d = res.data
        if (d.status !== 1) {
          message.error(d.message).then(null, null)

          reject(new Error(d.message))
        } else {
          resolve(d)
        }
      }).catch((e) => {
        const { basic } = store.getState()
        const { status, data } = e.response
        if (basic.token === '') {
          if (history.location.pathname !== '/login') {
            history.push('/login')
          }
          message.error('未登录').then(null, null)
          return reject(e)
        }
        if (status === 401 || (status === 500 && data.message === '登录超时')) {
          message.error(token !== '' ? '登录超时' : '请先登录', 2).then(null, null)
          store.dispatch(setToken(''))
          store.dispatch(setUserInfo({
            app_default: '',
            desktop: '',
            employeeid: '',
            id: '',
            is_auth: 0,
            mobile: '',
            realname: '',
            role_default: ''
          }))
          history.push('/login')
        } else if (status === 504) {
          message.error('网络异常', 2).then(null, null)
        } else {
          message.error(data.message, 2).then(null, null)
        }
        reject(e)
      })
    })
  }
}

// 需要鉴权的请求
export const $get: RequestFn = request('get', true)
export const $delete: RequestFn = request('delete', true)
export const $post: RequestFn = request('post', true)
export const $put: RequestFn = request('put', true)

// 不需要鉴权的请求
export const $freeGet: RequestFn = request('get', false)
export const $freeDelete: RequestFn = request('delete', false)
export const $freePost: RequestFn = request('post', false)
export const $freePut: RequestFn = request('put', false)

// 上传单个文件请求
export const requestOneFile = async function (file: File): Promise<UploadRes> {
  const config = {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  }
  const formData = new FormData()
  formData.append('upload_file', file)
  const res = await $post('/api/common/upload', formData, config)
  if (res.status !== 1) {
    throw new Error(res.message)
  }
  return res.data
}

// 上传多个文件请求
export const requestFiles = async function (files: File[]): Promise<UploadRes[]> {
  const list = files.map(requestOneFile)
  return await Promise.all(list)
}
